//
// Created by twetec on 25-8-16.
//

#ifndef NETWORK_PROBER_PROBE_DETECT_HANDLE_HTTP_PROBE_DETECT_H
#define NETWORK_PROBER_PROBE_DETECT_HANDLE_HTTP_PROBE_DETECT_H

#include <future>

namespace boost::json
{
struct value_from_tag;
struct value;
}

namespace network_prober::probe_detect
{
/**
 * HTTP IPv4 探测结果
 */
struct HTTPProbeDetectResultIPv4
{
    std::string interface;
    std::string target;
    std::int64_t delay;
    std::uint16_t port;

    friend std::ostream& operator<<(std::ostream& out, const HTTPProbeDetectResultIPv4& result);
};

/**
 * 探测结果 序列化
 * 注：保证 tag_invoke函数 与 TCPProbeDetectResult类 在同一个命名空间
 */
void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, HTTPProbeDetectResultIPv4 const &c);

/**
 * HTTP IPv4
 */
class HandleHTTPProbeDetectIPv4 : public std::enable_shared_from_this<HandleHTTPProbeDetectIPv4>
{
public:
    /**
     *  探测
     */
    void detect();

    /**
     * 探测到时回调
     */
    void setOnDetectedCallback(std::function<void(HTTPProbeDetectResultIPv4&&)> callback);

    // struct HandleHTTPProbeDetectIPv4Options
    // {
    //     std::string_view interface;
    //     std::string_view target;
    //     std::uint32_t port;
    //     std::string_view responseCode;
    //     bool ignoreTsl;
    //     std::string_view requestMethod; //  目标端口
    //     std::string_view requestHeader;  // 地址类型 ipv4/ipv6
    //     std::string_view requestBody;
    //     bool responseChallenge;
    //     std::string_view userName;
    //     std::string_view password;
    //     std::string_view keywords;
    // };

    /**
     * @param interface 网口地址
     * @param target 目标地址
     */
    HandleHTTPProbeDetectIPv4(
        std::string_view interface,
        std::string_view target,
        std::string_view responseCode,
        bool ignoreTsl,
        std::string_view requestMethod, //  目标端口
        std::string_view requestHeader,  // 地址类型 ipv4/ipv6
        std::string_view requestBody,
        bool responseChallenge,
        std::string_view userName,
        std::string_view password,
        bool matchCondition,
        std::string_view keyWords
    );
    ~HandleHTTPProbeDetectIPv4();

private:
    std::string m_interface;
    std::string m_target{};
    std::string m_responseCode;
    bool m_ignoreTsl;
    std::string m_requestMethod; //  目标端口
    std::string m_requestHeader;  // 地址类型 ipv4/ipv6
    std::string m_requestBody;
    bool m_responseChallenge;
    std::string m_userName;
    std::string m_password;
    bool m_matchCondition;
    std::string m_keyWords;
    std::function<void(HTTPProbeDetectResultIPv4&&)> m_onDetectedCallback;
    std::future<void> m_detectFuture;
};


/**
 * HTTP IPv6 探测结果
 */
struct HTTPProbeDetectResultIPv6
{
    std::string interface;
    std::string target;
    std::int64_t delay;
    std::uint16_t port;

    friend std::ostream& operator<<(std::ostream& out, const HTTPProbeDetectResultIPv6& result);
};

/**
 * HTTP 探测结果 序列化
 * 注：保证 tag_invoke函数 与 TCPProbeDetectResult类 在同一个命名空间
 */
void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, HTTPProbeDetectResultIPv6 const &c);

/**
 * HTTP IPv6
 */
class HandleHTTPProbeDetectIPv6 : public std::enable_shared_from_this<HandleHTTPProbeDetectIPv6>
{
public:
    /**
     *  探测
     */
    void detect();

    /**
     * 探测到时回调
     */
    void setOnDetectedCallback(std::function<void(HTTPProbeDetectResultIPv6&&)> callback);

    /**
     * @param interface 网口地址
     * @param target 目标地址
     */
    HandleHTTPProbeDetectIPv6(
        std::string_view interface,
        std::string_view target,
        std::string_view responseCode,
        bool ignoreTsl,
        std::string_view requestMethod, //  目标端口
        std::string_view requestHeader,  // 地址类型 ipv4/ipv6
        std::string_view requestBody,
        bool responseChallenge,
        std::string_view userName,
        std::string_view password,
        bool matchCondition,
        std::string_view keyWords
    );
    ~HandleHTTPProbeDetectIPv6();

private:
    std::string m_interface;
    std::string m_target{};
    std::string m_responseCode;
    bool m_ignoreTsl;
    std::string m_requestMethod; //  目标端口
    std::string m_requestHeader;  // 地址类型 ipv4/ipv6
    std::string m_requestBody;
    bool m_responseChallenge;
    std::string m_userName;
    std::string m_password;
    bool m_matchCondition;
    std::string m_keyWords;
    std::function<void(HTTPProbeDetectResultIPv6&&)> m_onDetectedCallback;
    std::future<void> m_detectFuture;
};

}



#endif //NETWORK_PROBER_PROBE_DETECT_HANDLE_HTTP_PROBE_DETECT_H
